package com.yuelife.market.rabbitmq;

import com.rabbitmq.client.Channel;
import com.yuelife.market.dao.MOrderDao;
import com.yuelife.market.dao.MProductDao;
import com.yuelife.market.entity.MOrder;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

//这里的消费订单，为了缓冲对数据订单的操作，并且将订单（默认未支付）放入到另外一个队列中，如果在另外一个队列中过期，那么就会又将其放入死信队列，最后被死信消费，修改数据库中的商品和redis中的缓存
@Component
public class OrderConsumer {

    @Autowired
    private MOrderDao mOrderDao;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    //队列的监听
    @RabbitListener(queues = "order-queue")//只要 order-queue 这个队列里面有数据，就会调用下面这个方法 orderQueue方法进行处理
    //RabbitHandler 用来标明消费者处理消息的方法；@Payload注解用来标明这是一个消息参数（生产者发送过来的）@Headers注解：标明用来获取消息请求头中的数据，可以在请求头中获取到消息的id，可以用在签收哪条消息
    @RabbitHandler
    public void orderQueue(@Payload MOrder mOrder, Channel channel, @Headers Map headers){
        //因为如果对数据库的访问很大，所以加个线程睡眠  缓冲0.5秒
//        try {
//            Thread.sleep(500);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        System.out.println("获取的订单消息编号"+ mOrder.getOrderSn());
        //得到对应消息的id，然后签收该消息
        Long id = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
        System.out.println("我是消息的id：："+id);
        //消息的签收
        try {
            channel.basicAck(id,false);//设置为false：不批量签收，如果是true会批量签收所有小于这个 id 的消息
        } catch (IOException e) {
            e.printStackTrace();
        }
        //如果消息签收未报异常，则往数据库插入订单消息
        //此时插入到数据库的订单消息是没有付款的订单
        this.mOrderDao.insert(mOrder);
        //因为初始化的订单是未付款的，所以把这些订单放入待支付队列中，由待支付队列管理，如果30分钟之后都没有付款，那么就成为失效订单，交给死信队列处理
        rabbitTemplate.convertAndSend("waitpay-exchange","waitpay."+mOrder.getOrderSn(),mOrder);
    }


}
